package models

import (
	"time"

	"github.com/beego/beego/v2/client/orm"
)

// Device 设备模型
type Device struct {
	BaseModel
	DeviceNo     string `orm:"size(64)" json:"device_no"`     // 设备编号
	DeviceName   string `orm:"size(100)" json:"device_name"`  // 设备名称
	DeviceType   int8   `orm:"default(1)" json:"device_type"` // 设备类型：0:门禁 1:其他
	StoreId      int64  `orm:"index" json:"store_id"`         // 所属门店ID
	VenueId      int64  `orm:"default(0)" json:"venue_id"`    // 所属房间ID（如果有）
	Status       int8   `orm:"default(1)" json:"status"`      // 状态：1:正常 0:离线 2:故障
	LastOnline   int64  `json:"last_online"`                  // 最后在线时间
	IpAddress    string `orm:"size(50)" json:"ip_address"`    // IP地址
	MacAddress   string `orm:"size(50)" json:"mac_address"`   // MAC地址
	ApiKey       string `orm:"size(256)" json:"api_key"`      // 设备API密钥
	ApiEndpoint  string `orm:"size(255)" json:"api_endpoint"` // 设备API接口地址
	Manufacturer string `orm:"size(100)" json:"manufacturer"` // 制造商
	Model        string `orm:"size(100)" json:"model"`        // 型号
	Firmware     string `orm:"size(50)" json:"firmware"`      // 固件版本
	Description  string `orm:"size(500)" json:"description"`  // 描述
}

// TableName 设置表名
func (d *Device) TableName() string {
	return "ss_device"
}

// GetDeviceById 根据ID获取设备信息
func GetDeviceById(id int64) (*Device, error) {
	device := &Device{BaseModel: BaseModel{Id: id}}
	o := orm.NewOrm()
	err := o.Read(device)
	return device, err
}

// GetDeviceByStoreId 根据门店ID获取设备列表
func GetDeviceByStoreId(storeId int64) ([]*Device, error) {
	o := orm.NewOrm()
	var devices []*Device
	_, err := o.QueryTable(new(Device)).Filter("store_id", storeId).Filter("is_deleted", 0).All(&devices)
	return devices, err
}

func GetDeviceByVenueId(venueId int64) ([]*Device, error) {
	o := orm.NewOrm()
	var devices []*Device
	_, err := o.QueryTable(new(Device)).Filter("venue_id", venueId).Filter("is_deleted", 0).All(&devices)
	return devices, err
}

// GetDeviceList 获取设备列表
func GetDeviceList(page, pageSize int, filters map[string]interface{}) ([]*Device, int64, error) {
	o := orm.NewOrm()
	qs := o.QueryTable(new(Device))

	// 应用过滤条件
	if storeId, ok := filters["store_id"].(int64); ok {
		qs = qs.Filter("store_id", storeId)
	}

	if deviceType, ok := filters["device_type"].(int8); ok {
		qs = qs.Filter("device_type", deviceType)
	}

	if status, ok := filters["status"].(int8); ok {
		qs = qs.Filter("status", status)
	}

	if keyword, ok := filters["keyword"].(string); ok && keyword != "" {
		conditions := orm.NewCondition()
		conditions = conditions.Or("device_no__icontains", keyword)
		conditions = conditions.Or("device_name__icontains", keyword)
		qs = qs.SetCond(conditions)
	}

	// 排除已删除的记录
	qs = qs.Filter("is_deleted", 0)

	// 获取总数
	total, _ := qs.Count()

	// 分页查询
	var devices []*Device
	_, err := qs.OrderBy("-id").Limit(pageSize, (page-1)*pageSize).All(&devices)

	return devices, total, err
}

// CreateDevice 创建设备
func CreateDevice(device *Device) (int64, error) {
	o := orm.NewOrm()
	device.CreatedAt = time.Now().Unix()
	device.UpdatedAt = device.CreatedAt
	id, err := o.Insert(device)
	return id, err
}

// UpdateDevice 更新设备信息
func UpdateDevice(device *Device, fields ...string) error {
	o := orm.NewOrm()
	device.UpdatedAt = time.Now().Unix()
	_, err := o.Update(device, fields...)
	return err
}

// DeleteDevice 删除设备（软删除）
func DeleteDevice(id int64) error {
	o := orm.NewOrm()
	device := &Device{BaseModel: BaseModel{Id: id}}
	if err := o.Read(device); err != nil {
		return err
	}

	device.IsDeleted = 1
	device.UpdatedAt = time.Now().Unix()
	_, err := o.Update(device, "IsDeleted", "UpdatedAt")
	return err
}

// UpdateDeviceStatus 更新设备状态
func UpdateDeviceStatus(id int64, status int8) error {
	o := orm.NewOrm()
	device := &Device{BaseModel: BaseModel{Id: id}}
	if err := o.Read(device); err != nil {
		return err
	}

	device.Status = status
	device.UpdatedAt = time.Now().Unix()
	if status == 1 { // 如果状态为在线，更新最后在线时间
		device.LastOnline = device.UpdatedAt
		_, err := o.Update(device, "Status", "UpdatedAt", "LastOnline")
		return err
	}

	_, err := o.Update(device, "Status", "UpdatedAt")
	return err
}
